﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace BIN
{
    public delegate bool DeleRetBool() ;
    public class MyThreadPool
    {
        private Control _ctl = null;
        private Action _MetHod = null;
        private Action _AftMetHod = null;
        private Action _BefMetHod = null;
        private DeleRetBool _WaitMetHod = null;
        private DateTime _begin = new DateTime(2000, 1, 1, 1, 1, 1);
        private DateTime _end = new DateTime(2000, 1, 1, 1, 1, 1);
        private bool _Finished = true;
        public event EventHandler OnThreadBegin, OnThreadFinished;
        public event EventHandler OnReadyBegin, OnReadyFinished;
        public DateTime BeginTime { get { return _begin; } }
        public DateTime EndTime { get { return _end; } }
        public bool Finished { get { return _Finished; } }
        public void SetBeforeMethod(Action befMethod)
        {
            _BefMetHod = befMethod;
        }
        public void SetReadyMethod(DeleRetBool readyMethod)
        {
            _WaitMetHod = readyMethod;
        }
        public int UsedSeconds
        {
            get
            {
                return (Int32)Math.Abs(ShareMet.DateDiff(DATEPART.SECOND, _begin, _end));
            }
        }
        public MyThreadPool(
            Control ctl,
            Action method,
            Action aftmethod)
        {
            _ctl = ctl;
            _MetHod = method;
            _AftMetHod = aftmethod;
        }
        public MyThreadPool(
           Control ctl,
           Action method,
           Action aftmethod,
           bool StartThread)
        {
            _ctl = ctl;
            _MetHod = method;
            _AftMetHod = aftmethod;
            if (StartThread) InvokeFunc();
        }
        public MyThreadPool(
            Control ctl,
            Action befMethod,
            Action Method,
            Action aftMethod,
            bool StartThread)
        {
            _ctl = ctl;
            _MetHod = Method;
            _AftMetHod = aftMethod;
            _BefMetHod = befMethod;
            if (StartThread) InvokeFunc();
        }
        public MyThreadPool(
           Control ctl,
           Action befMethod,
           Action Method,
           Action aftMethod,
           DeleRetBool waitMethod,
           bool StartThread)
        {
            _ctl = ctl;
            _MetHod = Method;
            _AftMetHod = aftMethod;
            _BefMetHod = befMethod;
            _WaitMetHod = waitMethod;
            if (StartThread) InvokeFunc();
        }
        private void ExecuteReadyMethod()
        {
            WaitControlHandleCreate();
            if (null != _ctl)
            {
                bool Ret = (bool)(_ctl.Invoke(_WaitMetHod));
                while (!Ret)
                {
                    Thread.Sleep(100);
                    Ret = (bool)(_ctl.Invoke(_WaitMetHod));
                }
            }
            else
            {
                bool Ret = _WaitMetHod();
                while (!Ret)
                {
                    Thread.Sleep(100);
                    Ret = _WaitMetHod();
                }
            }
        }
        private void WaitControlHandleCreate()
        {
            if (null != _ctl)
            {
                while (!_ctl.IsHandleCreated) Thread.Sleep(100);
            }
        }
        private void CallWaitSimpleDo(object SimpDo)
        {
            if (null != OnReadyBegin) OnReadyBegin(null, null);
            ExecuteReadyMethod();
            if (null != OnReadyFinished) OnReadyFinished(null, null);
            if (null != SimpDo)
            {
                Action func = (SimpDo as Action);
                if (null != _BefMetHod && null != _ctl)
                {
                    WaitControlHandleCreate();
                    if (null != _ctl)
                        _ctl.Invoke(_BefMetHod);
                    else
                        _BefMetHod();
                }
                if (null != func && _ctl != null)
                {
                    _begin = DateTime.Now;
                    _Finished = false;
                    if (null != OnThreadBegin) OnThreadBegin(null, null);
                    func.BeginInvoke(ThreadCallBack, func);
                }
            }
        }
        private void CallSimpleDo(object SimpDo)
        {
            if (null != SimpDo)
            {
                if (null == _BefMetHod) WaitControlHandleCreate();
                Action func = (SimpDo as Action);
                if (null != _BefMetHod && null != _ctl)
                {
                    //WaitControlHandleCreate();
                    if (null != _ctl)
                        _ctl.Invoke(_BefMetHod);
                    else
                        _BefMetHod();
                }
                if (null != func && _ctl != null)
                {
                    _begin = DateTime.Now;
                    _Finished = false;
                    if (null != OnThreadBegin) OnThreadBegin(null, null);
                    func.BeginInvoke(ThreadCallBack, func);
                }
            }
        }
        private void ThreadCallBack(IAsyncResult AsynResult)
        {
            if (AsynResult == null) return;
            if (AsynResult.IsCompleted)
            {
                _end = DateTime.Now;
                _Finished = true;
                if (null != OnThreadFinished) OnThreadFinished(null, null);
                if (null != _AftMetHod)
                {
                    WaitControlHandleCreate();
                    if (null != _ctl)
                        _ctl.Invoke((Action)_AftMetHod);
                    else
                        _AftMetHod();
                }
            }
        }
        public void InvokeFunc()
        {
            if (!_Finished) throw new Exception("There was a thread running!");
            if (null == _WaitMetHod)
                ThreadPool.QueueUserWorkItem(CallSimpleDo, _MetHod);
            else
                ThreadPool.QueueUserWorkItem(CallWaitSimpleDo, _MetHod);
        }
    }
}
